feat: funkit checkout integration for Core-market supplies#3010
Open
yogurtandjam wants to merge 11 commits into
Open
feat: funkit checkout integration for Core-market supplies#3010yogurtandjam wants to merge 11 commits into
yogurtandjam wants to merge 11 commits into
Conversation
* feat: route allowlisted Core-market supplies through funkit checkout Adds a funkit checkout path for USDC/USDT/WBTC/cbBTC supplies on the Core mainnet market, mirroring the production Polymarket integration: - FunkitCheckout: ssr:false modal host in _app (next to the app's other modal hosts), single useFunkitCheckout instance, per-asset configs via beginCheckout(configOverride). Honors the SDK's onLoginFinished resume contract by replaying it once ConnectKit connects. - funSupplyBridge: module-level imperative bridge across the client-only island boundary; clicks before the chunk loads fall back to the native supply modal. - funSupplyAssets: allowlist holds only what live reserve data can't provide (real on-chain aToken symbols — wallet_watchAsset validates against the contract — and absolute icon URLs for EIP-747). Everything else (symbol, decimals, addresses, pool) comes from the clicked reserve + current market store. Gated on CustomMarket.proto_mainnet_v3 so Prime/EtherFi reserves of the same underlyings stay native. - funkitPreflight.css: scoped, zero-specificity slice of Tailwind preflight under [data-rk] — @funkit/connect relies on host preflight for form-control font inheritance and img max-width (its production hosts are Tailwind apps; this one isn't). - patches/@Funkit+connect: React 18 forwardRef shim for funkit's React 19 ref-as-prop components, applied via patch-package. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: always show fun-routed assets in supply list regardless of balance fun checkout lets users supply from any EVM asset or fiat, so an empty wallet must not hide the row or disable the Supply button for allowlisted Core-market assets: - SupplyAssetsList dust filter: fun-routed reserves always pass - SupplyAssetsListItem / SupplyAssetsListMobileItem: zero wallet balance no longer disables Supply for fun-routed reserves (protocol-level blocks - inactive/frozen/paused/capped - still apply) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: pin FUN_SUPPLY_ASSETS aToken symbols to the address-book tokenlist The catalog hardcodes receipt-token symbols (dashboard reserve data only carries aTokenAddress; importing the 352KB/895-entry tokenlist at runtime for 4 strings is a bad bundle trade). This test imports the tokenlist where bundle size doesn't matter and fails CI if an address-book bump or catalog typo ever disagrees - wallets validate wallet_watchAsset symbols against the contract, so drift breaks the add-to-wallet flow. Loaded via a node subprocess: the package's CJS tokenlist artifact is data-less (its only module.exports is esbuild's dead-code annotation) and next/jest forbids transforming node_modules, so neither artifact is importable in-process under jest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: source funkit receipt-token data from app state The @aave/react SDK migration means useAppDataContext().supplyReserves already carries each reserve's aToken Currency (address, symbol, decimals, imageUrl) - the same state AddTokenDropdown renders on reserve-overview. Look it up at the Supply click instead of keeping integrator-owned copies: - FUN_SUPPLY_ASSETS catalog (hardcoded aToken symbols + icon URLs) shrinks to FUN_SUPPLY_UNDERLYINGS, a 4-address allowlist Set - purely the product decision of which assets route through fun checkout - useSupplyButtonAction resolves the SDK reserve and threads aToken/underlyingToken metadata through the bridge; falls back to the native modal if SDK market data isn't loaded yet - receipt icon improves: actual aToken artwork from aToken.imageUrl instead of reusing the underlying's icon - deletes the address-book drift test (nothing hardcoded left to drift) and its node-subprocess workaround for the tokenlist's broken CJS artifact; drops the decimals/aTokenAddress threading from list items - removes stray console.log debug block in SupplyAssetsListItemMobile Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: register the ringed aToken icon via fun checkout add-to-wallet The native flow's wallet icon is generated, not hosted: Base64Token wraps the underlying's local SVG in Aave's gradient TokenRing and base64-encodes it (Success.tsx / AddTokenDropdown). The SDK's aToken.imageUrl points at a plain third-party logo (token-logos.family.co), so the fun checkout's add-to-wallet icon didn't match. Per-row generation, mirroring AddTokenDropdown: fun-routed supply rows mount a hidden Base64Token via the shared useFunSupplyATokenIcon hook and pass the data URI through the click payload - explicit data flow, ready at row mount, never delays beginCheckout. Hosted imageUrl stays as the fallback for a click that beats generation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: drop unused tronweb dependency tronweb isn't a @funkit/connect dependency or peer, isn't referenced in its bundle, and nothing in this repo imports it - a leftover from early integration setup. Its exact bignumber.js@9.1.2 pin hoisted over the repo's ^9.0.2 -> 9.3.1 resolution, hiding the UMD global type that upstream's PriceInput.tsx relies on post-rebase. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@yogurtandjam is attempting to deploy a commit to the Aave Team on Vercel. A member of the Team first needs to authorize it. |
tronweb is a peerDependency of @relayprotocol/relay-tron-wallet-adapter, statically imported via @funkit/connect -> @funkit/fun-relay. pnpm auto-installs peers (why funkit's monorepo never trips on it); yarn v1 doesn't, so the host must declare it - removing it broke `next build` with "Module not found: Can't resolve 'tronweb'". Its exact bignumber.js@9.1.2 pin used to hoist over the repo's ^9.0.2 -> 9.3.x resolution, hiding the BigNumber UMD global type that PriceInput.tsx relies on. Solved via the repo's existing resolutions block: "bignumber.js": "^9.3.1" collapses all ranges to one 9.3.1 copy. Verified with a full `next build` (clean compile, 17/17 pages). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
❌ CI run has failed! |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Bump @funkit/connect 9.18.0 -> 9.19.0, and its hard deps to match (@funkit/api-base 4.4.1 -> 4.5.0, @funkit/chains 1.2.0 -> 2.0.0). 9.19.0 ships PaddedScrollableArea as forwardRef natively, so the React 18 compatibility patch is no longer needed -- drop patches/@Funkit+connect+9.18.0.patch. The native-flow toggle now always shows (runtime behavior in the new build, no code change required). Verified: all SDK exports the app uses still exist, buildFunSupplyConfig matches AaveSupplyCheckoutInput, single deduped chains resolution, and tsc --noEmit passes clean. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sammdec
requested changes
Jun 9, 2026
sammdec
left a comment
Contributor
There was a problem hiding this comment.
Some small initial changes requested
|
❌ CI run has failed! |
Addresses @sammdec's review comments. The patch-package patch is gone (SDK bumped to @funkit/connect 9.19.0, which ships the PaddedScrollableArea forwardRef fix natively) and .nvmrc now requires node 20.19, so the supporting scaffolding is dead: - delete .yarnrc (ignore-engines) — node 20.19 satisfies @solana/addresses' >=20.18 - package.json: drop the "postinstall": "patch-package" script + patch-package devDep - .prettierignore: drop the *.patch and .yarnrc entries - .gitignore: revert *.tsbuildinfo -> tsconfig.tsbuildinfo (matches upstream) - regenerate yarn.lock (patch-package removed) yarn install verified clean on node 20.19 with .yarnrc removed (no engines error). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…6) (#3) The demo-key fallback was the only use of @funkit/api-base; the funkit API key now comes solely from NEXT_PUBLIC_FUNKIT_API_KEY. The package remains a pinned transitive dep of @funkit/connect, so no resolved versions change. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* chore: set eslint root:true so nested worktrees lint cleanly Without root:true, linting inside a git worktree under .claude/worktrees/ cascades up to the outer checkout's .eslintrc.js and ESLint aborts with 'Plugin "prettier" was conflicted', failing the pre-commit hook. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: floor sub-0.01% supply APY display to <0.01 in funkit checkout A tiny-but-nonzero rate rendered as 0.00% in the funkit modal's Supply APY row and subtitle. Floor anything that rounds to 0.00 to "<0.01" (Aave's own FormattedNumber convention), so the APY never reads as zero — which also lets the SDK render the value unconditionally green (ENG-4215, funkit PR #5398). funkit only string-interpolates the value, so the non-numeric form is safe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The checkout SDK's same-asset guard (isSameAsPurchasingToken) is bypassed for checkouts with a post-deposit action, so supplying e.g. USDC while holding USDC preselected USDC as the payment source and auto-continued past source selection. Passing the underlying in disabledSourceTokens routes it through the SDK's isAllowed gate, which both blocks the auto-continue (hasUsableBalance) and greys the asset out in the picker. Scoped to the target chain so the same token on other chains remains a valid bridge-and-supply source. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The markets detail view (ReserveActions) opened the native Aave supply modal directly, bypassing the funkit checkout the dashboard supply list already used. Extract the funkit branch into a single <FunSupplyButton> component (action hook + ringed-aToken icon generator + Button passthrough) and use it for every Supply entry point so the branch can't be forgotten. - ReserveActions routes through FunSupplyButton; an empty wallet no longer disables fun-allowlisted assets (only a maxed supply cap does), matching the list. Native fallback preserves funnel='reserve'/isReserve and the wrapped-base-asset (native ETH) toggle. - useSupplyButtonAction gains optional funnel/isReserve (defaults keep list-item behavior identical). - collateralEnabled shown in the funkit modal now uses the user-level usageAsCollateralEnabledOnUser, matching the list call sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…NG-4228) Per review: the reserve-overview page was overriding disableSupplyButton at the call site to keep fun-allowlisted assets supplyable on an empty wallet. Push that rule into useReserveActionState (its only consumer) instead — it already has supplyCap, currentMarket and the reserve in scope. ReserveActions drops the override plus the redundant useAssetCaps/isFunSupplyAsset wiring and just consumes disableSupplyButton. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Routes Supply for 4 allowlisted assets (USDC, USDT, WBTC, cbBTC) on the Core mainnet market through the funkit checkout modal, letting users supply from any EVM asset or fiat. All other assets/markets keep the native Aave supply flow.
How
Integration architecture
FunkitCheckout—ssr:falsemodal host mounted once in_appnext to the app's other modal hosts (SupplyModaletc.). Owns the singleuseFunkitCheckoutinstance; per-asset configs are passed at call time viabeginCheckout(configOverride). Reuses the app's wagmi + react-query + ConnectKit (no funkit wallet stack). Honors the SDK'sonLoginFinishedresume contract by replaying it once ConnectKit connects.funSupplyBridge— module-level imperative bridge across the client-only island boundary (@funkit/connectis browser-only ESM; the app pre-renders/static-exports). The island registersbeginSupplyon mount; Supply buttons invoke it at click time. Clicks before the chunk loads fall back to the native modal instead of dropping.useSupplyButtonAction— single shared click handler for all 3 Supply list-item variants; gates onisFunSupplyAsset(currentMarket, underlyingAsset).Data sourcing — no integrator-owned copies
FUN_SUPPLY_UNDERLYINGS: a 4-address allowlist Set — purely the product decision of which assets route through fun checkout.aEthUSDC, decimals, hosted icon) comes from app state:useAppDataContext().supplyReserves(@aave/reactSDK reserves whoseaToken/underlyingTokenareCurrencyobjects) — the same sourceAddTokenDropdownrenders on reserve-overview. Display fields (symbol, APY, collateral state) come from the clicked dashboard reserve; pool address fromcurrentMarketData.CustomMarket.proto_mainnet_v3(not chainId): mainnet hosts three markets (Core/Prime/EtherFi) and e.g. USDC exists in all three with different aTokens and pools. Prime/EtherFi supplies of the same underlyings stay native. If SDK market data hasn't loaded at click time, the click falls back to the native modal.Add-to-wallet icon parity
The native flow's wallet icon is generated, not hosted:
Base64Tokenwraps the underlying's local SVG in Aave's gradientTokenRingand base64-encodes it. Fun-routed supply rows mount the same hidden generator via the shareduseFunSupplyATokenIconhook (theAddTokenDropdownpattern) and pass the data URI through the click payload — ready at row mount, never delaysbeginCheckout. The SDK's hostedaToken.imageUrlis the fallback for a click that beats generation.Zero-balance behavior
fun-routed assets always render in "Assets to supply" and keep an enabled Supply button at 0 wallet balance (users can pay with any asset/fiat). Protocol-level blocks (inactive/frozen/paused/capped) still disable.
Styling shim
funkitPreflight.css— a zero-specificity (:where()) slice of Tailwind preflight scoped under funkit's[data-rk]portal root.@funkit/connectimplicitly relies on host Tailwind preflight (its production hosts are Tailwind apps) for form-control font inheritance andimg { max-width: 100% }; this app is MUI/emotion. Without it the amount-input digits render in system font at weight 400 and host-supplied icons paint at intrinsic size.Compat
patches/@funkit+connect+9.18.0.patch— React 18forwardRefshim for funkit's React 19 ref-as-prop components (patch-package, wired via postinstall)..yarnrcignore-engines—@solana/addresses(transitive) requires node ≥20.18 while the repo targets node 18; browser-only code, engines gate is install-only.Not in scope (flagged for follow-up)
ReserveActions.tsx) and SuppliedPositions "supply more" buttons still go native — product decision pending.addToWalletToken.iconSrcresolver (consume-time semantics) would remove the begin-time icon coupling for all integrators.Test plan
🤖 Generated with Claude Code